#ifndef quantlib_linearregression_i 
#define quantlib_linearregression_i 

// %include options.i 
// %include linearalgebra.i 
// %include vectors.i 
 %include termstructures.i 
// %include stochasticprocess.i 
// %include types.i 


%{ 
using QuantLib::LinearRegression; 
using QuantLib::LinearLeastSquaresRegression; 
using QuantLib::PathPricer; 
using QuantLib::Path; 
//using QuantLib::TimeGrid; 
// using QuantLib::EarlyExercisePathPricer; 
using QuantLib::EarlyExerciseTraits; 
//using QuantLib::LongstaffSchwartzPathPricer; 
typedef boost::shared_ptr<LinearRegression> LinearRegressionPtr; 
//typedef boost::function1 
%} 

%rename(LinearRegression) LinearRegressionPtr; 
class LinearRegressionPtr  { 
        public: 
        %extend 
                {                         
                        LinearRegressionPtr( const std::vector<Real>& x, 
                                                                const std::vector<Real>& y) { 
                                return new LinearRegressionPtr(new LinearRegression(x, y)); 
                        } 
                        
                        LinearRegressionPtr(const std::vector<std::vector<Real> >& x, 
                         const std::vector<Real>& y) { 
                                return new LinearRegressionPtr(new LinearRegression(x, y)); 
                        } 
                        
                        const Array& coefficients()   const { 
                                return (*self)->coefficients(); 
                        } 
                        
                        const Array& residuals()      const { 
                                return (*self)->residuals(); 
                        } 
                        
                        const Array& standardErrors() const { 
                                return (*self)->standardErrors(); 
                        } 
                } 
}; 



template <class PathType> 
class EarlyExerciseTraits { 
        // dummy definition, will not work 
}; 

template <> 
class EarlyExerciseTraits<Path> { 
        public: 
                typedef Real StateType; 
                static Size pathLength(const Path& path); 
}; 


template <class ArgumentType = Real> 
class LinearLeastSquaresRegression { 
        public: 
                   
                LinearLeastSquaresRegression( const std::vector<ArgumentType>& x, 
                                                        const std::vector<Real>& y, 
                                                        const std::vector<boost::function1<Real, ArgumentType> > & v) ;                                                           
                                                        
                const Array& coefficients()   const { 
                        return (self)->coefficients(); 
                } 
                
                const Array& residuals()      const { 
                        return (self)->residuals(); 
                } 

}; 

%template(LinearLeastSquaresRegressionReal) LinearLeastSquaresRegression<Real>; 

%{ 
using QuantLib::LsmBasisSystem; 
%} 


class LsmBasisSystem { 
        public: 
                enum PolynomType { Monomial, Laguerre, Hermite, Hyperbolic, 
                            Legendre, Chebyshev, Chebyshev2nd }; 
        public: 
                %extend { 
                                std::vector<boost::function1<Real, Real> >        pathBasisSystem(Size order, LsmBasisSystem::PolynomType polynomType) { 
                                        return (*self).pathBasisSystem(order, polynomType); 
                                } 
                } 
}; 


#endif
